﻿/**
 * @file libmath.c
 * @brief this is a brief description
 * @details this is the detail description.
 * @author fulong 
 * @data 6/23/2014
 * @version 1.0
 * @par Copyright (c):
 * @par First build
 *     version: fulong 
 *     data: 6/23/2014
 */
#include "libmath.h"

/*! \brief 数字转换成16进制或者是2进制字符串格式
 * \param disnum 要转换的数字
 * \param disbuf 转换后,数字字符串保存在这里
 * \param hex_or_bin 指定需要什么格式输出. 
 *          1.h 代表是16进制输出 
            2.b 代表是2进制输出
 * \retrun
 */
math_status oct_transfer(uint16 disnum, uint8 *disbuf, const uint8 hex_or_bin, const uint8 zero_on) {
    uint8 num_char[ 16 ] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    uint8 buf1[ 32 ];                       //转换缓冲区.
    uint8 *temp = buf1;
    uint8 i;
    if ('H' == hex_or_bin) {
        for (i = 0; i < 6; i++) {
            num_char[10 + i] = 'A' + i;
        }
    }
#ifdef PARAM_CHECK
    if ((hex_or_bin != 'b') && (hex_or_bin != 'h') && (hex_or_bin != 'H') && (hex_or_bin != 'B') && (hex_or_bin != 'D') && (hex_or_bin != 'd')) return (WRONG);
#endif
    if (disnum) {
        switch (hex_or_bin) {
            case 'b': //2进制
            case 'B': //2进制
                while (disnum) {
                    //由低位开始转换为2进制代码
                    *temp = num_char[disnum % 2];
                    disnum >>= 1;
                    temp++;
                }
                break;

            case 'h': //16进制
            case 'H': //16进制
                while (disnum) {
                    //由低位开始转换为16进制代码
                    *temp = num_char[disnum % 16];
                    disnum >>= 4;
                    temp++;
                }
                break;

            case 'd': //10进制
            case 'D': //10进制
                while (disnum) {
                    //由低位开始转换为16进制代码
                    *temp = num_char[disnum % 10];
                    disnum /= 10;
                    temp++;
                }
                break;
            default:
                break;
        }
        //保存转后的数字串
        while ((--temp) != buf1) {
            *(disbuf++) = *temp;
        }
        *disbuf = *temp;
        if (1 == zero_on) {
            *(disbuf + 1) = 0;
        }

        return (RIGHT);
    }
    *disbuf = '0';
    if (1 == zero_on) {
        *(disbuf + 1) = 0;
    }
    return (RIGHT);
}
/*! \brief 16进制数字字符串转换 
 * 这个转换函数,数字的高位在数据的低位,数字的低位在数组的高位. 
 * \param disbuf 要转换的目标数字串,十六进制是用小写字幕
 * \retrun 返回转换成功后的数字.
 */
uint16 hexchar2num(uint8 *disbuf) {
    uint8 i, bit = 0;
    uint8 tmp;
    uint16 sum = 0;
    uint16 count = 1;
//  求出数字串的总位数.
    while (*(disbuf + bit) != 0) {
        bit++;
    }
    for (i = bit - 1; bit > 0; bit--, i--) {
        if ((*(disbuf + i) >= '0') && (*(disbuf + i) <= '9')) {
            tmp = *(disbuf + i) - '0';
        } else {
            if ((*(disbuf + i) >= 'a') && (*(disbuf + i) <= 'f')) {
                tmp = *(disbuf + i) - 'a' + 10;
            } else if ((*(disbuf + i) >= 'A') && (*(disbuf + i) <= 'F')) {
                tmp = *(disbuf + i) - 'A' + 10;
            } else {
                return (0);
            }
        }
        sum = sum + tmp * count;
        count *= 16;
    }
    return (sum);
}
void num_array2string(uint8 *num_array, uint8 *string, uint8 len) {
    uint8 i;
    for (i = 0; i < len; i++) {
        *(string + i * 2) = '0';
        *(string + i * 2 + 1) = '0';
        oct_transfer(num_array[i], string + i * 2, 'H', 0);
        if (num_array[i] < 16) {
            *(string + i * 2 + 1) = *(string + i * 2);
            *(string + i * 2) = '0';
        }
    }
    *(string + i * 2) = 0;
}
